package com.itcc.controller;

import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import com.itcc.controller.fun_handle.HandleBusiness;
import com.itcc.domain.LoginRequest;
import com.itcc.domain.User;
import com.itcc.domain.VisitLog;
import com.itcc.service.UserService;

import com.itcc.service.VisitLogService;
import eu.bitwalker.useragentutils.UserAgent;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Arrays;
import java.util.stream.Collectors;

@CrossOrigin    // 解决跨域问题
@RestController
@RequestMapping("/commService") //  请求映射
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private VisitLogService visitLogService;

    // 日志记录
    private static final Logger logger = Logger.getLogger(UserController.class.getName());

    /**
     * 注册
     * @param user 用户信息
     * @return Result对象，包含状态码和消息
     */
    @PostMapping("/register")
    public Result register(@RequestBody User user) {
        logger.log(Level.INFO, "用户注册：" + user.getUsername() + " " + user.getPassword());

        String[] username = userService.getUserName();

        if (username != null) {
            // 先排序（如果数组未预先排序）
            Arrays.sort(username);

            //返回注册用户名存在的索引，如果不存在则返回负数
            int index = Arrays.binarySearch(username, user.getUsername());
            if (index >= 0) {   //表示存在
                return new Result(Code.USER_EXIST, "用户名已经存在！");
            }else {
                String rawPassword = user.getPassword();
                String encodedPassword = BCrypt.hashpw(rawPassword, BCrypt.gensalt());      //加密

                User encryptUser = new User();
                encryptUser.setUsername(user.getUsername());
                encryptUser.setPassword(encodedPassword);

                boolean isRegister = userService.register(encryptUser.getUsername(), encryptUser.getPassword());

                return isRegister ? new Result(Code.REGISTER_SUCCESS) : new Result(Code.REGISTER_ERROR);
            }
        }
        return new Result(Code.REGISTER_ERROR);
    }

    /**
     * 登录页面
     * @return ModelAndView对象，包含视图名称
     */
    @PostMapping("/login")
    public Result login(@RequestBody LoginRequest loginRequest, HttpSession session) {

        logger.log(Level.INFO, "用户登录：" + loginRequest.getUsername() + " " + loginRequest.getPassword());

        // 获取前端传来的验证码
        String inputCaptcha = loginRequest.getCaptcha();
        // 从 session 中获取生成的验证码
        String captchaInSession = (String) session.getAttribute("captchaCode");

        if (inputCaptcha == null || !inputCaptcha.equalsIgnoreCase(captchaInSession)) {
            return new Result(Code.CAPTCHA_ERROR, "密码或验证码错误！");
        }

        String[] username = userService.getUserName();

        if (username != null) {
            Arrays.sort(username);
            int index = Arrays.binarySearch(username, loginRequest.getUsername());
            if (index < 0) {
                return new Result(Code.USER_NOT_EXIST, "用户名不存在, 请前往注册或重新登录！");
            } else {
                User loginUser = userService.login(loginRequest.getUsername());
                if (loginUser != null && BCrypt.checkpw(loginRequest.getPassword(), loginUser.getPassword())) {
                    // 登录成功，将用户信息放入 session
                    session.setAttribute("user", loginRequest.getUsername());
                    return new Result(Code.LOGIN_SUCCESS);
                } else {
                    return new Result(Code.LOGIN_ERROR, "密码或验证码错误！");
                }
            }
        }
        return new Result(Code.LOGIN_ERROR);
    }

    /**
     * 获取验证码
     * @param response HttpServletResponse对象
     * @param session HttpSession对象
     * @throws IOException 抛出 IOException
     */
    @GetMapping("/captcha")
    public void getCaptcha(HttpServletResponse response, HttpSession session) throws IOException {
        // 设置响应为图片格式
        response.setContentType("image/png");

        // 配置 Kaptcha
        Properties props = new Properties();
        props.put("kaptcha.image.width", "150");
        props.put("kaptcha.image.height", "60");
        props.put("kaptcha.session.key", "captchaCode"); // 存入 session 的 key
        props.put("kaptcha.textproducer.char.string", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
        props.put("kaptcha.textproducer.char.length", "4");

        Config config = new Config(props);
        DefaultKaptcha kaptcha = new DefaultKaptcha();
        kaptcha.setConfig(config);

        // 生成验证码文本和图片
        String capText = kaptcha.createText();
        BufferedImage image = kaptcha.createImage(capText);

        // 将验证码存入 session
        session.setAttribute("captchaCode", capText);

        // 输出图片到客户端
        OutputStream out = response.getOutputStream();
        ImageIO.write(image, "png", out);
    }

    /**
     * 退出登录
     * @return ModelAndView对象，包含视图名称(首页 index.jsp)
     */
    @GetMapping("/exitU")
    public ModelAndView exitU(HttpSession session) {

        // 从session中移除名为"user"的属性，以注销用户或清除其信息
        session.removeAttribute("user");
        session.invalidate();

        ModelAndView exitUser = new ModelAndView();
        exitUser.setViewName("redirect:/");
        return exitUser;
    }

    /**
     * 获取用户ip
     * @param session session
     * @return ModelAndView
     */
    @GetMapping("/userIp.do")
    public ModelAndView getUserIp(HttpSession session) {

        ModelAndView loginRedirect = new ModelAndView();

        // 判断是否登录（session中是否有user）
        if (session.getAttribute("user") == null){    //未登录
            loginRedirect.setViewName("redirect:/");
            return loginRedirect;
        }

        //  获取用户 IP
        String inetAddress = HandleBusiness.getLocalInetAddress();
        loginRedirect.addObject("user_ip", inetAddress);   //传递IP

        //用户已登录，正常返回
        loginRedirect.setViewName("userIp");

        return loginRedirect;
    }

    /**
     * 获取用户 Cookies
     * @param session session
     * @param request request
     * @return ModelAndView
     */
    @GetMapping("/cookies.do")
    public ModelAndView getUserCookiesMsg(HttpSession session, HttpServletRequest request) {

        ModelAndView userCookies = new ModelAndView();

        if (session.getAttribute("user") == null){    //未登录
            userCookies.setViewName("redirect:/");
            return userCookies;
        }

        //获取所有cookies
        Map<String, String> cookies = HandleBusiness.getAllCookies(request);
        String cookieStr = cookies.entrySet().stream()
                .map(e -> e.getKey() + "=" + e.getValue())
                .collect(Collectors.joining(", "));

        userCookies.addObject("cookie_msg", cookieStr);   //传递数据

        //用户登录，正常返回
        userCookies.setViewName("cookies");

        return userCookies;
    }

    /**
     * 获取用户Cookies信息
     * @param session session
     * @param request request
     * @return ModelAndView
     */
    @GetMapping("/userAgent.do")
    public ModelAndView getUserBrowserMsg(HttpSession session, HttpServletRequest request) {

        ModelAndView userBrowserMsg = new ModelAndView();

        if (session.getAttribute("user") == null){    //未登录
            userBrowserMsg.setViewName("redirect:/");
            return userBrowserMsg;
        }

        // 获取请求的User-Agent头部信息
        String userAgent = request.getHeader("User-Agent");
        // 获取浏览器和操作系统详情
        UserAgent userAgentMsg = UserAgent.parseUserAgentString(userAgent);
        // 获取浏览器名称
        String browser = userAgentMsg.getBrowser().getName();
        // 获取浏览器版本
        String version = userAgentMsg.getBrowserVersion() != null ? userAgentMsg.getBrowserVersion().getVersion() : "未知";
        // 获取操作系统名称
        String os = userAgentMsg.getOperatingSystem().getName();
        // 格式化解析到的浏览器和操作系统信息
        String parsedInfo = String.format("浏览器: %s %s\n操作系统: %s", browser, version, os);
        //传递数据
        userBrowserMsg.addObject("user_browser_msg", parsedInfo);
//        System.out.println("\033[32;4m" + userAgent + "\033[0m");

        //用户登录，正常返回
        userBrowserMsg.setViewName("userAgent");

        return userBrowserMsg;
    }

    /**
     * 获取uirViews页面
     * @return ModelAndView对象，包含视图名称
     */
    @GetMapping("/uirViews.do")
    public ModelAndView uirView(HttpSession session) {
        ModelAndView  loginRedirect = new ModelAndView();

        if (session.getAttribute("user") == null){    //未登录
            loginRedirect.setViewName("redirect:/");    //重定向到登录页面 index.jsp
            return loginRedirect;
        }

        List<VisitLog> allUserLogMsg = visitLogService.getAllUserLogMsg();
        loginRedirect.addObject("uir_views_msg", allUserLogMsg);

        //用户已登录，正常返回
        loginRedirect.setViewName("uirViews");
        return loginRedirect;
    }

}
